home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-06-16 | 13.3 KB | 419 lines | [TEXT/MMCC] |
- //
- // Application: LabelMenu
- //
- // Description: This demonstrates a program with a Finder-like label menu.
- // Each label menu item has a 12x16 pixel 'cicn and the
- // color and name of all the items are updated if the user
- // changes anything in the "Labels" control panel.
- // This also demonstrates how to change a menu tile to an icon.
- //
- // Programmer: David Hayward
- // Developer Technical Support
- // Apple Computer, Inc.
- //
- // Environment: Metrowerks C version 6, Universal Interfaces 2.0
- //
- // History: 11/23/93
- // first draft
- // 4/8/94
- // updated project to use the new Universal Header
- // added routine to change a menu title
- // added abillity to change Label menu's title to a small icon
- // (for info on how this is done see IM:Text page 7-39
- // 5/12/95
- // updated project for Metrowerks
- //
-
-
- #include <desk.h>
- #include <dialogs.h>
- #include <fonts.h>
- #include <icons.h>
- #include <windows.h>
- #include <memory.h>
- #include <menus.h>
- #include <quickdraw.h>
- #include <resources.h>
- #include <toolutils.h>
- #include <types.h>
-
- #include "InitMac.h"
-
-
- /**\
- |**| ==============================================================================
- |**| ENUMS
- |**| ==============================================================================
- \**/
- enum { kWindID=128 } ;
- enum { kMBarID=128 } ;
- enum { kAppleMenu=128, kFileMenu, kEditMenu, kLabelMenu, kSpecialMenu } ;
- enum { kNewItem=1, kOpenItem, kCloseItem, kSaveItem,
- kSaveAsItem, kFileBlank1, kPageSetupItem,
- kPrintItem, kFileBlank2, kQuitItem } ;
- enum { kDimLabel=1, kUseIcon } ;
- enum { kLabelIconID=1024 } ;
-
-
- /**\
- |**| ==============================================================================
- |**| GLOBALS
- |**| ==============================================================================
- \**/
- WindowPtr gWindow;
- Boolean gDone = false;
- Str255 gString = "\pInitial string"; /* default display string */
- Str255 LabelIconStr = "\p\01XXXX"; /* a five character string used to change label */
- /* menu's title to a small icon:
- /* Byte 0 = 0x05 = length if p-string */
- /* Byte 1 = 0x01 = invalid character code */
- /* Byte 2-5 = handle to icon suite */
- short theLabelItem=1; /* default label menu item (none) */
- Handle theLabelIcon;
-
-
- /**\
- |**| ==============================================================================
- |**| FUNCTION PROTOTYPES
- |**| ==============================================================================
- \**/
- void main ( void ) ;
- void SetUpMenus ( void ) ;
- void CreateWindow ( void ) ;
- void SetupLabelMenu ( void ) ;
- short Label2Item ( short label ) ;
- short Item2Label ( short item ) ;
- void DoCommand ( long mResult ) ;
- void DoUpdate ( WindowPtr whichWindow ) ;
- void DoMouseDown ( EventRecord event ) ;
- void DoOSEvent ( EventRecord event ) ;
- void DoEventLoop ( void );
-
- extern void SetMenuTitle (MenuHandle theMenu, Str255 theNewTitle);
-
-
- /**\
- |**| ==============================================================================
- |**| PRIVATE FUNCTIONS
- |**| ==============================================================================
- \**/
-
-
- /*------------------------------------------------------------------------------*\
- main
- *------------------------------------------------------------------------------*
- a fairly normal main function.
- \*------------------------------------------------------------------------------*/
- void main ( void )
- {
- InitToolBox( 4 ) ;
- SetUpMenus() ;
- CreateWindow() ; /* create main window */
- DoEventLoop() ;
- }
-
-
- /*------------------------------------------------------------------------------*\
- SetUpMenus
- *------------------------------------------------------------------------------*
- load in and draw the menu bar.
- \*------------------------------------------------------------------------------*/
- void SetUpMenus ( void )
- {
- Handle hMenuBar ;
- long *longPtr ;
-
- hMenuBar = GetNewMBar( kMBarID ) ;
- SetMenuBar( hMenuBar ) ;
- AddResMenu( GetMHandle(kAppleMenu), 'DRVR' ) ;
- SetupLabelMenu() ;
- DrawMenuBar() ;
-
- /* get icon suite for lable menu */
- GetIconSuite( &theLabelIcon, kLabelIconID, svAllSmallData ) ;
- HNoPurge( (Handle)theLabelIcon ) ;
-
- /* stuff the handle for the suite into chars 2-5 of the label string */
- longPtr = (long *)&(LabelIconStr[2]) ;
- *longPtr = (long)theLabelIcon ;
- }
-
-
- /*------------------------------------------------------------------------------*\
- CreateWindow
- *------------------------------------------------------------------------------*
- Create a normal window in front and a big
- window in back to obscure the Finder.
- \*------------------------------------------------------------------------------*/
- void CreateWindow ( void )
- {
- gWindow = GetNewCWindow( kWindID, nil, nil ) ;
- }
-
-
- /*------------------------------------------------------------------------------*\
- SetupLabelMenu
- *------------------------------------------------------------------------------*
- this function updates the label menu so that the items contain the
- current label text and color. note that this uses the trick of
- directly changing the color in the the icon of each item. The offset
- of 29 for the RGB color will only work for the included 24x12 'cicn's
- \*------------------------------------------------------------------------------*/
- void SetupLabelMenu ( void )
- {
- Str255 labelString ;
- RGBColor labelColor ;
- short label, item, rID, depth ;
- CIconHandle cicon ;
- GDHandle gdh ;
- MenuHandle LabelMenuHdl ;
-
- LabelMenuHdl = GetMHandle( kLabelMenu ) ;
- gdh = GetMainDevice() ; /* get device with the menu bar */
- depth = (**(**gdh).gdPMap).pixelSize; /* get the depth of this screen */
-
- /* special case for 1st label */
- /* because "none" item has no */
- GetLabel( 0, &labelColor, labelString ) ; /* icon next to it */
- SetItem( LabelMenuHdl, 1, labelString ) ; /* set label string */
-
- for ( label=1; label<8; label++ ) /* loop through other labels... */
- {
- item = Label2Item( label ) ; /* calc menu item for this label */
-
- GetLabel( label, &labelColor, labelString ) ; /* get the label string and color */
- SetItem( LabelMenuHdl, item, labelString ) ; /* set label string */
-
- if ( depth<=2 ) /* if screen too shallow... */
- SetItemIcon( LabelMenuHdl, item, 0 ) ; /* turn off the menu item's 'cicn' */
- else /* if screen deep enough... */
- {
- rID = 310 + label - 256 ; /* calclate 'cicn' code */
- SetItemIcon( LabelMenuHdl, item, rID ) ; /* set it for the menu item */
-
- cicon = (CIconHandle)GetResource('cicn', rID+256) ;
-
- if ( cicon!=nil ) /* resource was found */
- {
- short *iMaskData = (**cicon).iconMaskData ;
- iMaskData[29] = labelColor.red ; /* change the color */
- iMaskData[30] = labelColor.green ;
- iMaskData[31] = labelColor.blue ;
- }
- }
- }
- }
-
-
- /*------------------------------------------------------------------------------*\
- Label / Item conversions
- *------------------------------------------------------------------------------*
- the standard order for labels in a menu is backwards so here
- are functions to convert back and forth. these could be #defines.
- \*------------------------------------------------------------------------------*/
- short Label2Item ( short label )
- { return ( (label==0) ? (0) : (10-label) ) ;
- }
- short Item2Label ( short item )
- { return ( (item==0) ? (0) : (10-item) ) ;
- }
-
-
- /*------------------------------------------------------------------------------*\
- DoCommand
- *------------------------------------------------------------------------------*
- handle menu events.
- \*------------------------------------------------------------------------------*/
- void DoCommand ( long mResult )
- {
- short item, menu, mark ;
- MenuHandle mHandle ;
-
- item = LoWord( mResult ) ;
- menu = HiWord( mResult ) ;
- mHandle = GetMHandle( menu ) ;
-
- if ( (menu!=0) && (item!=0) ) /* if any menu item ... */
- {
- GetItem( mHandle, item, gString ) ; /* get the item's text */
- SetPort( (GrafPtr)gWindow ) ;
- InvalRect( &(gWindow->portRect) ) ; /* start and update event */
- }
-
- switch (menu)
- {
- case kLabelMenu : /* if the the label menu... */
- CheckItem( mHandle, theLabelItem, false ) ; /* uncheck the old */
- CheckItem( mHandle, item, true ) ; /* check the new */
- theLabelItem = item ; /* remember the item */
- break ;
-
- case kSpecialMenu : /* if the the Special menu... */
- if ( item==kDimLabel ) /* if dim label item... */
- {
- GetItemMark( mHandle, item, &mark ) ; /* determine if already checked */
- CheckItem( mHandle, item, !mark ) ; /* check/uncheck the item */
- if (mark==0) /* dim/undim the label menu */
- DisableItem( GetMHandle(kLabelMenu), 0 ) ;
- else
- EnableItem( GetMHandle(kLabelMenu), 0 ) ;
- DrawMenuBar() ; /* update the menu bar */
- }
- if ( item==kUseIcon )
- {
- GetItemMark( mHandle, item, &mark ) ; /* determine if already checked */
- CheckItem( mHandle, item, !mark ) ; /* check/uncheck the item */
- if ( mark==0 ) /* change the label menu to show icon*/
- SetMenuTitle( GetMHandle(kLabelMenu), LabelIconStr ) ;
- else
- SetMenuTitle( GetMHandle(kLabelMenu), "\pLabel" ) ;
- }
- break ;
-
- case kFileMenu : /* if the the file menu... */
- if ( item==kQuitItem ) /* if quit item... */
- gDone = true ;
- break ;
- }
- HiliteMenu(0); /* un-hilight the chosen menu item */
- }
-
-
- /*------------------------------------------------------------------------------*\
- DoUpdate
- *------------------------------------------------------------------------------*
- handle update events.
- \*------------------------------------------------------------------------------*/
- void DoUpdate ( WindowPtr window )
- {
- RGBColor labelColor = {0,0,0} ;
- Str255 labelString ;
-
- BeginUpdate( window ) ;
- SetPort( window ) ; /* make sure we're in our port */
-
- GetLabel( Item2Label(theLabelItem), /* get the currently checked */
- &labelColor, labelString) ; /* label's rgb color */
- RGBForeColor( &labelColor ) ; /* set it as the fore color */
-
- EraseRect( &((GrafPtr)window)->portRect ) ; /* erase the old stuff */
-
- TextSize( 24 ) ;
- MoveTo( 20, 80 ) ;
- DrawString( gString ) ; /* draw the string */
-
- EndUpdate( window ) ;
- }
-
-
- /*------------------------------------------------------------------------------*\
- DoMouseDown
- *------------------------------------------------------------------------------*
- handle DoMouseDown events.
- \*------------------------------------------------------------------------------*/
- void DoMouseDown ( EventRecord event )
- {
- WindowPtr window ;
- short clickArea ;
- Rect screenRect ;
-
- clickArea = FindWindow( event.where, &window ) ;
- screenRect = (**GetGrayRgn()).rgnBBox ;
-
- switch ( clickArea )
- {
- case inSysWindow:
- SystemClick( &event, window ) ;
- break;
-
- case inMenuBar: /* handle menu selections */
- DoCommand( MenuSelect(event.where) ) ;
- break;
-
- case inDrag : /* handle window drags */
- DragWindow( window, event.where, &screenRect ) ;
- break;
-
- case inContent : /* Handle content clicks */
- // if ( window != FrontWindow() ) /* if click is in a back window */
- // if ( window != gBackWind ) /* and its not gBackWind */
- // SelectWindow( window ); /* the bring it to front */
- break;
-
- case inGoAway :
- // if ( TrackGoAway(window,event.where) )
- // HideWindow( window ) ; /* hide the window */
- // if ( window==gForeWind ) /* if it was the fore wind */
- // gForeVis = false ; /* then update its state global */
- break;
- }
- }
-
-
- /*------------------------------------------------------------------------------*\
- DoOSEvent
- *------------------------------------------------------------------------------*
- handle DoOSEvent events.
- \*------------------------------------------------------------------------------*/
- void DoOSEvent ( EventRecord event )
- {
- long mssg ;
-
- mssg = event.message ;
- if ( (mssg>>24)==suspendResumeMessage ) /* if high byte of message indicates */
- { /* this is suspend/resume event */
- if ( mssg & resumeFlag ) /* if resume event */
- {
- /* we're switching back from another app so we need to update */
- /* the label menu in case the user changed the labels */
- SetupLabelMenu() ;
- }
- else /* if suspend event */
- {
- /* we're switching to another app */
- }
- }
- }
-
-
- /*------------------------------------------------------------------------------*\
- DoEventLoop
- *------------------------------------------------------------------------------*
- Keep doing an event loop until the user quits.
- \*------------------------------------------------------------------------------*/
- void DoEventLoop ( void )
- {
- EventRecord event ;
- WindowPtr window ;
- long mssg ;
-
- while ( !gDone )
- {
- if ( WaitNextEvent(everyEvent,&event,30,nil) )
- {
- mssg = event.message ;
- switch ( event.what )
- {
- case mouseDown : /* handle mouse clicks */
- DoMouseDown( event ) ;
- break ;
-
- case keyDown : /* handle key hits */
- case autoKey :
- if ( event.modifiers & cmdKey ) /* handle command keys */
- DoCommand(MenuKey( mssg & charCodeMask) ) ;
- break ;
-
- case updateEvt : /* handle update events */
- DoUpdate( (WindowPtr)mssg ) ;
- break ;
-
- case osEvt: /* handle os events */
- DoOSEvent( event ) ;
- break ;
- }
- }
- }
- }
-
-